package com.mediator;

import com.mediator.Annotations.CommandHandler;
import com.mediator.Annotations.EnableCommandHandler;
import com.mediator.Annotations.PipeLine;
import com.mediator.Mediator.IMediator;
import com.mediator.Mediator.impl.Mediator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.*;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.type.filter.AnnotationTypeFilter;

import java.util.Set;

@Configuration
public class MediatorConfiguration {

    @Autowired
    private ApplicationContext context;
    public MediatorConfiguration()
    {

    }
    @Bean
    public IMediator InjectMediator()
    {
        var enable=context.getBeansWithAnnotation(EnableCommandHandler.class);
        if (!enable.isEmpty())
        {
            var application=enable.values().iterator().next();
            EnableCommandHandler handler = AnnotationUtils.findAnnotation(application.getClass(), EnableCommandHandler.class);
            if (handler!=null)
            {
                var path=handler.path();
                if (!path.isEmpty())
                {ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) context;
                    DefaultListableBeanFactory factory=(DefaultListableBeanFactory)configurableApplicationContext.getBeanFactory();
                    var allCommandClass=scanCommandHandlerClasses(path);
                    if (!allCommandClass.isEmpty())
                    {
                        for(BeanDefinition item:allCommandClass)
                        {
                            var name=item.getBeanClassName();
                            item.setScope("request");
                            factory.registerBeanDefinition(name,item);
                        }
                    }
                    var pipeClass=scanPipeLineClasses(path);
                    if (!pipeClass.isEmpty())
                    {
                        for(BeanDefinition item:pipeClass)
                        {
                            var name=item.getBeanClassName();
                            item.setScope("request");
                            factory.registerBeanDefinition(name,item);
                        }
                    }
                }
            }
        }
        return new Mediator();
    }
    private   Set<BeanDefinition> scanCommandHandlerClasses(String basePackage) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        ClassPathBeanDefinitionScanner scanner =
                new ClassPathBeanDefinitionScanner(context,true);
        // 添加过滤条件，只扫描带有 @CommandHandler 注解的类
        scanner.addIncludeFilter(new AnnotationTypeFilter(CommandHandler.class));
        // 扫描指定包路径
        Set<BeanDefinition> candidates = scanner.findCandidateComponents(basePackage);
        return candidates;
    }
    private   Set<BeanDefinition> scanPipeLineClasses(String basePackage) {

        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        ClassPathBeanDefinitionScanner scanner =
                new ClassPathBeanDefinitionScanner(context,true);
        // 添加过滤条件，只扫描带有 @PipeLine 注解的类
        scanner.addIncludeFilter(new AnnotationTypeFilter(PipeLine.class));
        // 扫描指定包路径
        Set<BeanDefinition> candidates = scanner.findCandidateComponents(basePackage);
        return candidates;
    }
}
